﻿#region

using System;
using System.IO;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using CuongHanh.Context;
using CuongHanh.DAL;
using CuongHanh.Models;
using CuongHanh.Models.View;
using CuongHanh.Security;
using Ext.Net;
using Ext.Net.MVC;

#endregion

namespace CuongHanh.Controllers.BO
{
    [CustomAuthorize(Key = "Management", Description = "Manage all apps")]
    public class AProductController : ABaseController
    {
        public ActionResult Index(int branchId)
        {
            //Random r = new Random();
            //for (int i = 0; i < 6; i++)
            //{
            //    var category = new Category()
            //                        {
            //                            BranchId = branchId,
            //                            Code = r.Next(123213, 999999) + "",
            //                            NameVi = "V-subCategory" + i,
            //                            NameEn = "E-subCategory" + i,
            //                            NameZh = "C-subCategory" + i,
            //                            No = i,
            //                            Invisible = false,
            //                            LastModified = DateTime.Now
            //                        };
            //    _unitOfWork.Insert(category);
            //    _unitOfWork.Save();
            //    CacheContext<Category>.Singleton.UpdateCached(category);
            //    for (int j = 0; j < 5; j++)
            //    {
            //        var subCategory = new SubCategory()
            //        {
            //            BranchId = branchId,
            //            CategoryId = category.Id,
            //            Code = r.Next(123213, 999999) + "",
            //            NameVi = "V-Category" + i,
            //            NameEn = "E-Category" + i,
            //            NameZh = "C-Category" + i,
            //            No = i,
            //            Invisible = false,
            //            LastModified = DateTime.Now
            //        };
            //        _unitOfWork.Insert(subCategory);
            //        _unitOfWork.Save();
            //        CacheContext<SubCategory>.Singleton.UpdateCached(subCategory);
            //    }
            //}

            //var categories = CacheContext<Category>.Singleton.GetObjectsByFilter(c => c.BranchId == branchId).ToList();
            //foreach (var category in categories)
            //{
            //    var subCategories = CacheContext<SubCategory>.Singleton.GetObjectsByFilter(c => c.CategoryId == category.Id).ToList();
            //    foreach (var subCategory in subCategories)
            //    {
            //        for (int i = 1; i < 11; i++)
            //        {
            //            var product = new Product(branchId)
            //                {
            //                    Code = r.Next(123213, 999999) + "",
            //                    CategoryId = category.Id,
            //                    SubCategoryId = subCategory.Id,
            //                    NameVi = "V-" + subCategory.NameVi + i,
            //                    NameEn = "E-" + subCategory.NameVi + i,
            //                    NameZh = "C-" + subCategory.NameVi + i,
            //                    Price = (int)(r.Next(111,
            //                                          999) * 100000),
            //                    IsShowIndex = i < 6,
            //                    BestSaler = i < 6,
            //                    BranchId = subCategory.BranchId,
            //                    Invisible = false,

            //                    CreateDate = DateTime.Now,
            //                    LastModified = DateTime.Now,
            //                    Image = "2.jpeg"
            //                };
            //            _unitOfWork.Insert(product);
            //            _unitOfWork.Save();
            //            for (int j = 0; j < 6; j++)
            //                _unitOfWork.Insert(new ProductImage(product.Id, "2.jpeg"));
            //            _unitOfWork.Save();
            //        }
            //    }

            //}
            //RouteConfig.RegisterRoutes(new RouteCollection());
            ViewBag.branchId = branchId;
            return View();
        }

        public ActionResult ShowAdd(string containerId,
                                    int branchId)
        {
            //ShowWindow(containerId,true);
            return ShowWindow("Add",
                              containerId,
                              new Product(branchId));
            return this.Direct();
        }

        public ActionResult ProductInfo(int id)
        {
            Product model = GetProduct(id);
            return View(model);
        }

        [HttpPost]
        public ActionResult Add(Product model)
        {
            Product newModel = new Product(model);
            UpdateResult result = InsertProduct(newModel);
            ShowWindow("wdModify",
                       false);
            ReloadStore("storeGvData");
            ShowNotification(result);
            return this.Direct();
        }

        public ActionResult Command(string containerId,
                                    string command,
                                    int id)
        {
            if(command == "Delete")
            {
                UpdateResult result = DeleteProduct(id);
                ReloadStore("storeGvData");
                ShowNotification(result);
            }
            if(command == "Edit")
            {
                Product model = GetProduct(id);
                return ShowWindow("Edit",
                                  containerId,
                                  model);
            }
            if(command == "DeleteProductImage")
            {
                UpdateResult result = DeleteProductImage(id);
                ReloadStore("storeGvData");
                ShowNotification(result);
            }
            if (command == "SetImageIsDefault")
            {
                UpdateResult result = SetImageIsDefault(id);
                ReloadStore("storeGvData");
                ShowNotification(result);
            }
            return this.Direct();
        }

        public ActionResult Edit(int id)
        {
            
            return View(id);
        }
        public ActionResult Images(int id)
        {

            return View(id);
        }

        [HttpPost]
        public ActionResult Edit(Product model)
        {
            UpdateResult result = UpdateProduct(model);
            //ShowWindow("wdModify",
            //           false);
            //ReloadStore("storeGvData");
            ShowNotification(result);
            return this.Direct();
        }

        public ActionResult GetDatas(int branchId,
                                     int start,
                                     int limit,
                                     string sort,
                                     string query)
        {
            return Content(GetProductsByBranch(branchId,
                                                start,
                                                limit,
                                                sort,
                                                query),
                           "json");
        }

        public ActionResult ShowAddImageForProduct(string containerId,
                                                   int productId)
        {
            return ShowWindow("AddImageForProduct",
                              containerId,
                              productId);
        }

        [HttpPost]
        public ActionResult AddImageForProduct(int productId,
                                               bool isDefault,
                                               HttpPostedFileBase files)
        {
            Product model = GetProduct(productId);
            UpdateResult result = new UpdateResult(4,
                                                   "Không tim thấy sản phẩm");
            if(model != null)
            {
                if(files != null
                   && files.ContentLength > 0)
                {
                    byte[] imgData = new byte[files.ContentLength];
                    files.InputStream.Read(imgData,
                                           0,
                                           files.ContentLength);
                    string fileName = WriteByteToFile(imgData,
                                                      files.InputStream);
                    if(!string.IsNullOrWhiteSpace(fileName))
                    {
                        if(isDefault)
                        {
                            if(!string.IsNullOrWhiteSpace(model.Image))
                                DeleteAllThisFile(model.Image);
                            model.Image = fileName;
                            result = UpdateProduct(model);
                        }
                        else
                        {
                            ProductImage item = new ProductImage(productId,
                                                                 fileName);
                            result = InsertProductImage(item);
                        }
                    }
                    ShowWindow("wdModify",
                               false);
                    ReloadStore("storeGvData");
                    ShowNotification(result);
                    return this.Direct();
                }
            }

            return this.Direct();
        }

        public ActionResult GetImagesByProduct1(int productId)
        {
            return Content(GetImagesByProduct(productId),
                           "json");
        }

        public ActionResult UploadClick( int productId)
        {
            string tpl = "Uploaded file: {0}<br/>Size: {1} bytes";

            if(this.GetCmp<FileUploadField>("FileUploadField1").HasFile)
            {
                FileUploadField fileUpload = this.GetCmp<FileUploadField>("FileUploadField1");
                byte[] imgData = fileUpload.FileBytes;

                
                    string fileName = WriteByteToFile(imgData,
                                                      fileUpload.FileContent);
                    if (!string.IsNullOrWhiteSpace(fileName))
                    {
                        ProductImage item = new ProductImage(productId,
                                                             fileName);
                        UpdateResult resultm = InsertProductImage(item);
                        //ShowNotification(resultm);
                        ReloadStore("storeGvData");
                    }
                    X.Msg.Show(new MessageBoxConfig
                                   {
                                       Buttons = MessageBox.Button.OK,
                                       Icon = MessageBox.Icon.INFO,
                                       Title = "Success",
                                       Message = string.Format(tpl,
                                                               this.GetCmp<FileUploadField>("FileUploadField1").PostedFile.FileName,
                                                               this.GetCmp<FileUploadField>("FileUploadField1").PostedFile.ContentLength)
                                   });
            }
            else
            {
                X.Msg.Show(new MessageBoxConfig
                               {
                                       Buttons = MessageBox.Button.OK,
                                       Icon = MessageBox.Icon.ERROR,
                                       Title = "Fail",
                                       Message = "No file uploaded"
                               });
            }
            DirectResult result = new DirectResult();
            result.IsUpload = true;
            return result;
        }

        #region Product

        private readonly UnitOfWork _unitOfWork = new UnitOfWork();

        public string GetProductsByBranch(int branchId,
                                           int start,
                                           int limit,
                                           string sort,
                                           string q)
        {
            IQueryable<Product> q1 = _unitOfWork.Where<Product>(c => c.BranchId == branchId && (c.NameVi.Contains(q) || c.NameEn.Contains(q) || c.NameZh.Contains(q)) && !c.Inactive);
            IQueryable<Category> q2 = _unitOfWork.Where<Category>(c => c.BranchId == branchId && !c.Inactive);
            IQueryable<SubCategory> q3 = _unitOfWork.Where<SubCategory>(c => c.BranchId == branchId && !c.Inactive);
            var query = q1.Join(q2,
                                c => c.CategoryId,
                                v => v.Id,
                                (c,
                                 v) => new
                                           {
                                                   c,
                                                   v
                                           })
                    .Join(q3,
                          c => c.c.SubCategoryId,
                          v => v.Id,
                          (c,
                           v) => new
                                     {
                                             c.c.Id,
                                             CategoryName = c.v.NameVi,
                                             SubCategoryName = v.NameVi,
                                             c.c.NameVi,
                                             c.c.NameEn,
                                             c.c.NameZh,
                                             c.c.Code,
                                             c.c.IsShowIndex,
                                             Picture = c.c.Image,
                                             c.c.Price,
                                             c.c.SaleOff,
                                             c.c.CreateDate,
                                             c.c.BestSaler
                                     });

            return FormatResult(query.Count(),
                                query.OrderBy(c => c.CategoryName).ThenBy(c => c.SubCategoryName).ThenBy(c => c.NameVi).Skip(start).Take(limit));
        }

        public Product GetProduct(int id)
        {
            return _unitOfWork.GetById<Product>(id);
        }

        public UpdateResult InsertProduct(Product model)
        {
            _unitOfWork.Insert(model);
            _unitOfWork.Save();
            CacheContext<Product>.Singleton.UpdateCached(model);
            //Cached.Sigleton.UpdateBestSaller(model);
            //Cached.Sigleton.UpdateNewProduct(model);
            return new UpdateResult(1,
                                    string.Format("Insert Product {0} successful!",
                                                  model.NameVi));
        }

       

        public UpdateResult UpdateProduct(Product newModel)
        {
            Product model = _unitOfWork.GetById<Product>(newModel.Id);
            if(model != null)
            {
                model.UpdateInfoFrom(newModel);
                _unitOfWork.Save();
                CacheContext<Product>.Singleton.UpdateCached(model);
                //Cached.Sigleton.UpdateBestSaller(model);
                //Cached.Sigleton.UpdateNewProduct(model);
                return new UpdateResult(1,
                                        string.Format("Update Product {0} successful!",
                                                      newModel.NameVi));
            }
            return new UpdateResult(4,
                                    string.Format("Update Product {0} error!",
                                                  newModel.NameVi));
        }

        public UpdateResult DeleteProduct(int id)
        {
            Product oldModel = _unitOfWork.GetById<Product>(id);
            if(oldModel != null)
            {
                oldModel.Delete();
                _unitOfWork.Save();
                CacheContext<Product>.Singleton.UpdateCached(oldModel);
                
                //Cached.Sigleton.UpdateBestSaller(oldModel);
                //Cached.Sigleton.UpdateNewProduct(oldModel);
                return new UpdateResult(1,
                                        string.Format("Delete Product {0} successful!",
                                                      id));
            }
            return new UpdateResult(4,
                                    string.Format("Delete Product {0} error!",
                                                  id));
        }

        public string GetProductsComboByBranch(int branchId)
        {
            var query = _unitOfWork.Where<Product>(c => c.BranchId == branchId && !c.Inactive)
                    .Select(c => new
                                     {
                                             c.Id,
                                             c.NameVi,
                                     }).OrderBy(c => c.NameVi).ToList();

            return FormatResult(query.Count,
                                query);
        }

        #endregion

        #region ProductImage

        public string GetImagesByProduct(int productId)
        {
            var product = _unitOfWork.GetById<Product>(productId);
            
            var query = _unitOfWork.Where<ProductImage>(c => c.ProductId == productId && !c.Inactive).Select(c => new
                                                                                          {
                                                                                                  c.Id,
                                                                                                  c.Image,
                                                                                                  IsDefault=false
                                                                                          }).ToList();
            if(product!=null)
                query.Insert(0,new
                              {
                                      Id=0,
                                      product.Image,
                                      IsDefault=true,
                              });

            return FormatResult(query.Count(),
                                query);
        }

        public ProductImage GetProductImage(int id)
        {
            return _unitOfWork.GetById<ProductImage>(id);
        }

        public UpdateResult InsertProductImage(ProductImage model)
        {
            _unitOfWork.Insert(model);
            _unitOfWork.Save();
            return new UpdateResult(1,
                                    string.Format("Insert ProductImage {0} successful!",
                                                  model.Image));
        }

        public UpdateResult UpdateProductImage(ProductImage newModel)
        {
            ProductImage model = _unitOfWork.GetById<ProductImage>(newModel.Id);
            if(model != null)
            {
                model.UpdateInfoFrom(newModel);
                _unitOfWork.Save();
                return new UpdateResult(1,
                                        string.Format("Update ProductImage {0} successful!",
                                                      newModel.Image));
            }
            return new UpdateResult(4,
                                    string.Format("Update ProductImage {0} error!",
                                                  newModel.Image));
        }

        public UpdateResult DeleteProductImage(int id)
        {
            ProductImage oldModel = _unitOfWork.GetById<ProductImage>(id);
            if(oldModel != null)
            {
                oldModel.Delete();
                _unitOfWork.Save();
                return new UpdateResult(1,
                                        string.Format("Delete ProductImage {0} successful!",
                                                      id));
            }
            return new UpdateResult(4,
                                    string.Format("Delete ProductImage {0} error!",
                                                  id));
        }

        public UpdateResult SetImageIsDefault(int id)
        {
            ProductImage productImage = _unitOfWork.GetById<ProductImage>(id);

            if ( productImage != null)
            {
                Product product = _unitOfWork.GetById<Product>(productImage.ProductId);
                if (product != null)
                {
                    var t = product.Image;
                    product.Image = productImage.Image;
                    product.LastModified = DateTime.Now;
                    productImage.Image = t;
                    productImage.LastModified = DateTime.Now;
                    _unitOfWork.Save();
                    CacheContext<Product>.Singleton.UpdateCached(product);
                    return new UpdateResult(1,
                                            "Thay đổi ảnh chính cho sản phẩm thành công!");
                }
            }
            return new UpdateResult(4,
                                    "Thay đổi ảnh chính cho sản phẩm thất bại!");
        }

        #endregion

        #region Acticle

        public ActionResult Article(int id)
        {
            Product product = new Product(){ Id = id };
            Product product1 = _unitOfWork.GetById<Product>(id);
            if (product1 != null)
                product.Article = product1.Article;
            return View(product);
        }

        [HttpPost]
        public ActionResult Article(Product model,
                                    FormCollection collection)
        {
            var product = _unitOfWork.GetById<Product>(model.Id);
            if(product != null && model.Id > 0
               && !string.IsNullOrWhiteSpace(model.Article))
            {
                string[] images = collection.GetValues("pictures");
                if(images != null)
                {
                    for (int i = 0; i < images.Length; i++)
                    {
                        WriteFileFromString64(string.Format("I_ARTICLE_{0}_{1}.jpg",
                                                            model.Id,
                                                            i),
                                              images[i]);
                    }
                }
                product.Article = model.Article;
                product.LastModified = DateTime.Now;
                _unitOfWork.Save();
            }

            return View(model);
        }

        #endregion

        #region Combobox
        public string GetCategoriesComboByBranch(int branchId)
        {

            var query = _unitOfWork.Where<Category>(c => c.BranchId == branchId && !c.Inactive)
                    .Select(c => new
                                     {
                                             c.Id,
                                             Name = c.NameVi,
                                     }).OrderBy(c => c.Name).ToList();

            return FormatResult(query.Count,
                                query);

        }

        public string GetSubCategoriesComboByBranch(int branchId, int categoryId)
        {
            var query = _unitOfWork.Where<SubCategory>(c => c.BranchId == branchId && c.CategoryId==categoryId && !c.Inactive)
                    .Select(c => new
                                     {
                                             c.Id,
                                             Name=c.NameVi,
                                     }).OrderBy(c => c.Name).ToList();

            return FormatResult(query.Count,
                                query);
        }

        #endregion
    }
}
